home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-11-19 | 7.8 KB | 201 lines | [TEXT/MPS ] |
- /*
- File: TArbitratorExample3.cp
-
- Contains: This module show an more complex example of how to use the TArbitrator class.
-
- Copyright: © 1993 by Apple Computer, Inc., all rights reserved.
-
- */
-
- #include "TInitSLM.h" // the TInitSLM class and SLM include files
-
- ///————————————————————————————————————————————————————————————————————————————————————
- /// CONSTANTS
- ///————————————————————————————————————————————————————————————————————————————————————
-
- // id of the object we register with the arbitrator
- #define kObjectID "tool:Arbt$MethodNotifier"
-
- ///————————————————————————————————————————————————————————————————————————————————————
- /// GLOBALS
- ///————————————————————————————————————————————————————————————————————————————————————
-
- TArbitrator *gArbitrator;
-
- ///————————————————————————————————————————————————————————————————————————————————————
- /// PROTOTYPES
- ///————————————————————————————————————————————————————————————————————————————————————
-
- static TToken* get_exclusive_access();
- static void request_token(TProcNotifier *requestNotifier);
- static void notify_owner( void*, EventCode, OSErrParm, void* theData );
- static void notify_requester( void*, EventCode, OSErrParm, void* theData );
-
- /*————————————————————————————————————————————————————————————————————————————————————
- main
-
- A Simple program demonstrating the use of TArbitrator & TToken. An object is created
- and then registered with the arbitrator. This results in a token be created for the
- object which is maintained by the arbitrator. When the object is then claimed for exclusive
- access the arbitrator gives up the token to the new owner. The new owner creates a
- a notifier for the token so it can be notified if anyone requests the token. A
- requester then creates a notifier so that when it requests the token it will be
- notified when it becomes available. When the request is made the owner's notifier
- gets called. He gives up the token which then causes the requestor's notifier to get
- called who then claims new ownership of the token.
-
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- main()
- {
- TInitSLM initLibraryManager; // initialize the shared library manager
-
- if( initLibraryManager.Failed() ) // If we failed, let's go home
- return 1;
-
- void *myobject = nil; // this object we will register with the arbitrator
- TToken *exclusivetoken = nil; // the token that will hold the object
-
- TRY
- gArbitrator = new TArbitrator; // create our own TArbitrator
- FailNULL( gArbitrator, ErrorCode(), "Sorry failed to create an arbitrator");
-
- // allocate a block of memory that we will register so others can access it
- myobject = new char[256];
- FailNULL( myobject, ErrorCode(), "Sorry failed to allocate memory for our object");
-
- Fail( gArbitrator->RegisterObject(kObjectID, myobject), "Unable to register" );
-
- cout << "Registering an object at " << myobject << endl;
-
- FailNULL( exclusivetoken = get_exclusive_access(), ErrorCode(), "Failed to get exclusive access" );
-
- // %%% Why are we creating these. Give info about their purpose
-
- // Create a notifier for the owner of the object/token. It will be called when someone
- // requests the token from the owner.
- TProcNotifier ownernotifier( notify_owner );
- exclusivetoken->SetNotifier( &ownernotifier );
-
- // Create a notifier for the requester of the object. It will be called when the
- // request is fullfilled.
- TProcNotifier requesternotifier( notify_requester );
- request_token(&requesternotifier);
- ENDTRY
-
- delete myobject; // clean up we are done
- delete gArbitrator; // You don't want this to hang-around, do you?
-
- return 0;
- }
-
- /*————————————————————————————————————————————————————————————————————————————————————
- get_exclusive_access
-
- call this routine once you have registered an object, and need to get exclusive
- access to the object. This routine also checks to see if the exclusive access
- was successful.
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- static TToken* get_exclusive_access()
- {
- TToken *exclusivetoken = gArbitrator->GetToken( kObjectID, kExclusiveTokenRequest );
-
- if( exclusivetoken ) { // we got exclusive access
-
- // Now let's try to access it and we should fail
- TToken *tmptoken = gArbitrator->GetToken( kObjectID, kExclusiveTokenRequest );
-
- if( tmptoken ) // hopefully tmptoken should be nil
- cout << "Hey, wait a minute! I was suppose to have exclusive access" << endl;
- else {
- cout << "Got exclusive access to the object at ";
- cout << (void*)exclusivetoken->GetObject() << endl;
- }
- }
-
- return exclusivetoken;
- }
-
- /*————————————————————————————————————————————————————————————————————————————————————
- request_token
-
- this routine is called to request the token even though someone else may already
- have exclusive access to it. We pass in a notifier that will be called when the
- owner gives up access to the token.
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- static void request_token(TProcNotifier *requesterNotifier)
- {
- // Call ActiveRequest to register a request for a token and notify the current
- // owner that request is pending, and return the TRequestToken. Once we have
- // the request token we unregister the requested token by deleting it or by
- // calling TRequestToken::Exchange, a method that returns the requested token
- // if it is available and deletes the request.
-
- TRequestToken* myrequest =
- gArbitrator->ActiveRequest( kObjectID, kExclusiveTokenRequest, requesterNotifier );
-
- if( myrequest ) {
- // The owner has been notified by now. If he didn't give up the token then
- // Exchange() will return NULL. If this ever happens you can wait around until
- // eventually the token is release at which time the requestor's notifer will
- // be called, or you can just give up and delete the request token.
-
- TToken *reqtoken = myrequest->Exchange();
- if( reqtoken ) { // this is the token we are looking for
- if( reqtoken->GetObject() ) {
- cout << "Now we can have an exclusive access to the object ";
- cout << "located at " << (void*)reqtoken->GetObject() << endl;
- }
- else {
- cout << "Sorry, the owner wont let go of the object.\n" << endl;
- delete myrequest; // We are done with our request
- }
- }
- }
- }
-
- /*————————————————————————————————————————————————————————————————————————————————————
- notify_owner
-
- This routine is called when a requester requests a registered token. Here the
- owner can decide whether or not to give up an owned object to a TRequestToken.
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- static void notify_owner( void* refPtr, EventCode, OSErrParm, void* theData )
- {
- TRequestToken *requestedtoken;
-
- cout << "TMyNotifier::NotifyOwner……";
-
- if( requestedtoken = ((TTokenNotification *)theData)->GetRequestToken() ) {
- // give up our exclusive access.
- cout << " giving up an owned object to TRequestToken" << endl;
- requestedtoken->Give(((TTokenNotification*)theData)->GetToken());
- }
- }
-
- /*————————————————————————————————————————————————————————————————————————————————————
- notify_requester
-
- This routine is called to notify the requester whether when the request
- has been granted. NotifyRequester can obtain the token by using the GetObject
- method of the requested token.
- ————————————————————————————————————————————————————————————————————————————————————*/
-
- static void notify_requester( void* refPtr, EventCode, OSErrParm, void* theData )
- {
- TRequestToken *requestedtoken;
-
- cout << "TMyNotifier::NotifyRequester……";
- if( requestedtoken = ((TTokenNotification *)theData)->GetRequestToken() ) {
- TToken* thetoken = (TToken *)requestedtoken->GetObject();
- if( thetoken ) {
- cout << "got the requested token, now the buffer at ";
- cout << (void*)thetoken->GetObject();
- cout << " is available"<<endl;
- }
- }
- }
-